﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using SHack.Helper;
using System.Threading;
using System.Diagnostics;
using SMDS;
using SMDS.Helper;


namespace SHack
{
    class PingScan:BaseScan
    {
        public delegate void ScanFoundPingHandler(string ip, int mills);
        public event ScanFoundPingHandler ScanFoundPingEvent;

        private Queue<string> _quIPS = new Queue<string>();
        private object _lockerIPS = new object();

        public bool Start(int threadCount,  string startIP, string endIP)
        {
            Regex reg = new Regex(@"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}");
            if (!reg.Match(startIP).Success)
            {
                _error = "起始IP地址不符合规则！";
                return false;
            }
            if (!reg.Match(endIP).Success)
            {
                _error = "起始结束地址不符合规则！";
                return false;
            }


            _quIPS.Clear();
            _lastTime = DateTime.Now;
            _passCount = 0;
            _totalCount = 0;
            _succCount = 0;

            _isrun = true;


            long sIP = IPHelper.IPToNumber(startIP);
            long eIP = IPHelper.IPToNumber(endIP);

            if (sIP > eIP)
            {
                long tmp = eIP;
                eIP = sIP;
                sIP = eIP;
            }

            for (long i = sIP; sIP <= eIP; sIP++)
            {
                string ip = IPHelper.NumberToIP(sIP);
                _quIPS.Enqueue(ip);
              
            }

            _totalCount = _quIPS.Count;
            for (int i = 0; i < threadCount; i++)
            {
                new Thread(thScanPing).Start();
            }
            return true;        
        }

        public bool Stop()
        {
            _isrun = false;
            return true;
        }

        private void thScanPing()
        {
            while (_isrun && _quIPS.Count > 0)
            {
                try
                {
                    string ip;
                    lock (_lockerIPS)
                    {
                        if (_quIPS.Count == 0)
                            break;

                        ip = _quIPS.Dequeue();

                    }
                    AddPass();

                    long pingRet = PingHelper.Ping(ip);
                    if (pingRet >= 0)
                    {
                        AddSucc();
                        if (ScanFoundPingEvent != null)
                            ScanFoundPingEvent(ip, (int)pingRet);
                    }


                }
                catch (Exception ex)
                {
                    Console.WriteLine("PingScan.cs->thScanStop()", ex.Message);
                }
            }


            CallStop();
    
        }

    }
}
